package com.the4man.framework.service.impl;

import com.the4man.framework.service.CacheFilter;
import com.the4man.framework.service.ICache;

import java.io.Serializable;
import java.util.*;

/**
 * Created by lenovo on 2017/12/12.
 */
public abstract class CacheBase implements Serializable, ICache {
    private static final long serialVersionUID = -7459350401500368073L;
    protected Map cacheContainer;

    public CacheBase() {
    }

    protected abstract boolean init() throws Exception;

    public abstract String getNameByKey(Object var1);

    public Object getObjectByKey(Object key) {
        if(key == null) {
            return null;
        } else if(this.cacheContainer.containsKey(key)) {
            return this.cacheContainer.get(key);
        } else {
            this.refreshByKey(key);
            return this.cacheContainer.containsKey(key)?this.cacheContainer.get(key):null;
        }
    }

    public abstract boolean refreshByKey(Object var1);

    public boolean refreshAll() {
        return false;
    }

    public Collection getAllCachedObject() {
        if(this.cacheContainer != null) {
            return this.cacheContainer.values();
        } else {
            this.refreshAll();
            return this.cacheContainer != null?this.cacheContainer.values():null;
        }
    }

    public Collection getAllCachedSortedObject() {
        if(this.cacheContainer == null) {
            this.refreshAll();
            if(this.cacheContainer == null) {
                return null;
            }
        }

        SortedMap sortContainer = new TreeMap();
        sortContainer.putAll(this.cacheContainer);
        return sortContainer.values();
    }

    public Map getObjectByCondition(CacheFilter cf) {
        Map ret = new Hashtable();
        Iterator en = this.cacheContainer.keySet().iterator();

        while(en.hasNext()) {
            Object tmpKey = en.next();
            Object tmpObj = this.cacheContainer.get(tmpKey);
            if(cf.match(tmpObj)) {
                ret.put(tmpKey, tmpObj);
            }
        }

        return ret;
    }

    public Collection getTailByCondition(CacheFilter cf, Object fromKey) {
        if(this.cacheContainer == null) {
            this.refreshAll();
            if(this.cacheContainer == null) {
                return null;
            }
        }

        SortedMap sortContainer = new TreeMap();
        Iterator en = this.cacheContainer.keySet().iterator();

        while(en.hasNext()) {
            Object tmpKey = en.next();
            Object tmpObj = this.cacheContainer.get(tmpKey);
            if(cf.match(tmpObj)) {
                sortContainer.put(tmpKey, tmpObj);
            }
        }

        /*SortedMap */sortContainer = sortContainer.tailMap(fromKey);
        return sortContainer.values();
    }

    public Collection getHeadByCondition(CacheFilter cf, Object toKey) {
        if(this.cacheContainer == null) {
            this.refreshAll();
            if(this.cacheContainer == null) {
                return null;
            }
        }

        SortedMap sortContainer = new TreeMap();
        Iterator en = this.cacheContainer.keySet().iterator();

        while(en.hasNext()) {
            Object tmpKey = en.next();
            Object tmpObj = this.cacheContainer.get(tmpKey);
            if(cf.match(tmpObj)) {
                sortContainer.put(tmpKey, tmpObj);
            }
        }

        /*SortedMap */sortContainer = sortContainer.headMap(toKey);
        return sortContainer.values();
    }

    public Collection getTailCachedObject(Object fromKey) {
        if(this.cacheContainer == null) {
            this.refreshAll();
            if(this.cacheContainer == null) {
                return null;
            }
        }

        SortedMap sortContainer = new TreeMap();
        sortContainer.putAll(this.cacheContainer);
        /*SortedMap */sortContainer = sortContainer.tailMap(fromKey);
        return sortContainer.values();
    }

    public Collection getHeadCachedObject(Object toKey) {
        if(this.cacheContainer == null) {
            this.refreshAll();
            if(this.cacheContainer == null) {
                return null;
            }
        }

        SortedMap sortContainer = new TreeMap();
        sortContainer.putAll(this.cacheContainer);
        /*SortedMap */sortContainer = sortContainer.headMap(toKey);
        return sortContainer.values();
    }

    public Collection getMidCachedObject(Object fromKey, Object toKey) {
        if(this.cacheContainer == null) {
            this.refreshAll();
            if(this.cacheContainer == null) {
                return null;
            }
        }

        SortedMap sortContainer = new TreeMap();
        sortContainer.putAll(this.cacheContainer);
        /*SortedMap */sortContainer = sortContainer.subMap(fromKey, toKey);
        return sortContainer.values();
    }

    public void removeObjectByKey(Object key) {
        if(this.cacheContainer.containsKey(key)) {
            this.cacheContainer.remove(key);
        }

    }

    public void putObject(Object key, Object value) {
        this.cacheContainer.put(key, value);
    }

    public Map getContainer() {
        return this.cacheContainer;
    }
}
